//package com.metis.document.parse.dialog.utils;
//
//import java.io.File;
//import java.io.IOException;
//import java.io.OutputStream;
//import java.lang.ref.Cleaner;
//import java.util.concurrent.atomic.AtomicInteger;
//
//import com.metis.document.parse.dialog.enums.FileTypeEnum;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.io.IOUtils;
//import org.jetbrains.annotations.NotNull;
//
//
///**
// * @author: wuzhijun
// * @date: 2022/12/21
// */
//@Slf4j
//public class TempFileOutputStream extends OutputStream implements AbstractTempFileIOStream {
//    private final File tempFile;
//    private final BufferedRandomAccessFile raFile;
//    private boolean closed = false;
//    private final static Cleaner cleaner = Cleaner.create();
//
//    public TempFileOutputStream(@NotNull FileTypeEnum fileType) {
//        try {
//            tempFile = createTmpFile(fileType);
//            REF_COUNT.put(tempFile, new AtomicInteger(1));
//            LOCK_MAP.put(tempFile, new Object());
//            this.raFile = new BufferedRandomAccessFile(tempFile, "rw");
//            log.debug("create temp OutputStreamFile: {}", tempFile.getAbsolutePath());
//            BufferedRandomAccessFile finalRaFile = raFile;
//            File finaTempFile = tempFile;
//            cleaner.register(this, ()->{
//                try {
//                    log.debug("auto clean temp file: {}", finaTempFile.getAbsolutePath());
//                    finalRaFile.close();
//                } catch (IOException e) {
//                    throw new RuntimeException(e);
//                }
//            });
//        } catch (IOException e) {
//            //出现未知异常，直接抛出
//            //理论上不应该进入这里
//            throw new AssertionError(e);
//        }
//    }
//
//    public TempFileOutputStream(@NotNull File tempFile) {
//        try {
//            REF_COUNT.compute(tempFile, (k, v) -> {
//                if (v == null) {
//                    return new AtomicInteger(1);
//                } else {
//                    v.incrementAndGet();
//                    return v;
//                }
//            });
//            LOCK_MAP.computeIfAbsent(tempFile, k -> new Object());
//            this.tempFile = tempFile;
//            this.raFile = new BufferedRandomAccessFile(tempFile, "rw");
//            log.debug("create temp OutputStreamFile: {}", tempFile.getAbsolutePath());
//        } catch (IOException e) {
//            //出现未知异常，直接抛出
//            //理论上不应该进入这里
//            throw new AssertionError(e);
//        }
//    }
//
//    @Override
//    public synchronized void close(){
//        if (closed) {
//            return;
//        }
//        IOUtils.closeQuietly(raFile);
//        synchronized (LOCK_MAP.get(tempFile)) {
//            REF_COUNT.computeIfPresent(tempFile, (k, v) -> {
//                v.decrementAndGet();
//                return v;
//            });
//            if (canDeleteTempFile()) {
//                //清空引用
//                LOCK_MAP.remove(tempFile);
//                REF_COUNT.remove(tempFile);
//                deleteTempFile();
//            }
//            closed = true;
//        }
//    }
//
//    @Override
//    public void write(int b) throws IOException {
//        raFile.write(b);
//    }
//
//    @Override
//    public void write(byte[] b, int off, int len) throws IOException {
//        raFile.write(b, off, len);
//    }
//
//    private boolean deleteTempFile() {
//        if (tempFile != null) {
//            log.debug("delete temp file: {}", tempFile.getAbsolutePath());
//            return tempFile.delete();
//        }
//        return false;
//    }
//
//    @Override
//    public boolean canDeleteTempFile() {
//        synchronized (LOCK_MAP.get(tempFile)) {
//            AtomicInteger count = REF_COUNT.get(tempFile);
//            return count != null && count.get() == 0;
//        }
//    }
//
//    @Override
//    public TempFileOutputStream clone() {
//        synchronized (LOCK_MAP.get(tempFile)) {
//            return new TempFileOutputStream(tempFile);
//        }
//    }
//
//    public TempFileInputStream toInputStream(){
//        return new TempFileInputStream(tempFile);
//    }
//}
